#include <numeric>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <cmath>
//#include <local.h>
using namespace std;
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<string> VS;
#define Rep(i,n) for(int i=0;i<(n);++i) 
#define For(i,a,b) for(int i=(a);i<=(b);++i) 
#define ForI(TP,i,coll) for(TP (i)=coll.begin();(i)!=coll.end();(i)++)
#define ForD(i,a,b) for(int i=(a);i>=(b);--i)
#define All(a) a.begin(), a.end()
typedef long long LL;

struct rc{ wstring s; LL fr; };
bool operator<(const rc& r1, const rc& r2)
{return r1.fr>r2.fr;} // pop elements with smallest frequency

priority_queue<rc> rcs;
void push_rc(const rc& r)
{
	rcs.push(r);
	if(rcs.size()>100)
		rcs.pop();
}


struct TNode
{
	typedef TNode *pointer;
	typedef map<wchar_t, TNode> Next_Type;

	bool bEnd;
	LL fr;
	Next_Type next;

	TNode()
	{
		bEnd=false;
		fr=0;
	}

	void add(const wchar_t* p)
	{
		fr++;
		wchar_t c=*p++;
		if(c==NULL)
		{
			bEnd=true;
			return;
		}
		next[c].add(p);
	}

	void gettop100(wstring& s) // mis-match tolerance
	{
		if(bEnd)
		{
			rc r={s, fr};
			push_rc(r);
		}

		//if(rcs.empty())
		for(Next_Type::iterator it=next.begin(); it!=next.end();it++)
		{
			s.push_back(it->first);
			// skip some
			if(!(rcs.size()>=100 && it->second.fr < rcs.top().fr))
			{
				it->second.gettop100(s);
			}
			s.erase(s.size()-1);
		}
	}
};

int main()
{
	setlocale(LC_ALL, "chs");

	wchar_t s[128];
	TNode n;
	while(scanf("%S", s)==1)
	{
		n.add(s);
	}

	wstring str;
	n.gettop100(str);

	while(rcs.size()>100)
		rcs.pop();

	while(!rcs.empty())
	{
		wcout<< rcs.top().s <<endl;
		rcs.pop();
	}

	return 0;
}